﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using com.eFORCE.CommonUtilsForSearch;

public partial class SearchInGridControl : System.Web.UI.UserControl
{
    #region Private Properties

    private string targetControlID;
    private List<string> listExcludedFields;
    List<string> lstcolumnsToSearch = new List<string>();
    private string filterCriteria;
    private string UniqueKey
    {
        get
        {
            return keyUnique.Value;
        }
        set
        {
            keyUnique.Value = value;
        }
    }
    private string SortExpressionOfTargetControl
    {
        get
        {
            string valueToReturn = null;
            switch (OriginalDataSourceStateManagementOption)
            {
                case OriginalDataSourceStateManagementOptions.UseSession:
                    valueToReturn = (string)Session[UniqueKey + "_SortExpression"];
                    break;
                case OriginalDataSourceStateManagementOptions.UseViewstate:
                    valueToReturn = (string)ViewState[UniqueKey + "_SortExpression"];
                    break;
            }
            return valueToReturn;
        }
        set
        {
            switch (OriginalDataSourceStateManagementOption)
            {
                case OriginalDataSourceStateManagementOptions.UseSession:
                    Session[UniqueKey + "_SortExpression"] = value;
                    break;
                case OriginalDataSourceStateManagementOptions.UseViewstate:
                    ViewState[UniqueKey + "_SortExpression"] = value;
                    break;
            }
        }
    }

    #endregion

    #region Public Properties


    [Browsable(true)]
    public string TargetControlID
    {
        get
        {
            if (string.IsNullOrEmpty(targetControlID))
                throw new NullReferenceException(
                    "You must bind to a control through the TargetControlId property before you use the Search Control");
            return targetControlID;
        }
        set { targetControlID = value; }
    }

    public GridView TargetControl
    {
        get
        {
            GridView gvTarget = null;
            Control cntrl = null;
            if (!string.IsNullOrEmpty(TargetControlID))
            {
                cntrl = LocateControl(this, TargetControlID);

            }
            if (cntrl != null)
            {
                gvTarget = (GridView)cntrl;
            }

            return gvTarget;
        }
    }

    [Browsable(true)]
    public string ExcludedFieldsCSV
    {
        get
        {
            string csv = "";
            foreach (string field in listExcludedFields)
            {
                csv += field + ",";
            }
            char[] charsToTrim = { ',' };
            csv.TrimEnd(charsToTrim);
            return csv;
        }
        set
        {
            listExcludedFields = value.Split(',').ToList();
        }
    }

    [Browsable(false)]
    public List<string> ExcludedFields
    {
        get
        {
            return this.listExcludedFields;
        }
        set
        {
            this.listExcludedFields = value;
        }
    }
    [Browsable(true)]
    public OriginalDataSourceStateManagementOptions OriginalDataSourceStateManagementOption
    {
        get;
        set;
    }

    [Browsable(false)]
    public object OriginalData
    {
        get
        {
            object valueToReturn = null;
            if (OriginalDataSourceStateManagementOption != OriginalDataSourceStateManagementOptions.UseNone)
            {

                if (!Page.IsPostBack)
                {
                    RetainedData = TargetControl.DataSource;

                }
                valueToReturn = RetainedData;
            }
            else
            {
                return TargetControl.DataSource;
            }
            return valueToReturn;
        }
    }

    private object RetainedData
    {
        get
        {
            object valueToReturn = null;
            switch (OriginalDataSourceStateManagementOption)
            {
                case OriginalDataSourceStateManagementOptions.UseSession:
                    valueToReturn = Session[UniqueKey + "_RetainedData"];
                    break;
                case OriginalDataSourceStateManagementOptions.UseViewstate:
                    valueToReturn = ViewState[UniqueKey + "_RetainedData"];
                    break;
            }
            return valueToReturn;
        }
        set
        {
            switch (OriginalDataSourceStateManagementOption)
            {
                case OriginalDataSourceStateManagementOptions.UseSession:
                    Session[UniqueKey + "_RetainedData"] = TargetControl.DataSource;
                    break;
                case OriginalDataSourceStateManagementOptions.UseViewstate:
                    ViewState[UniqueKey + "_RetainedData"] = TargetControl.DataSource;
                    break;
            }
        }
    }

    [Browsable(false)]
    public object FilteredData { get; set; }

    public enum OriginalDataSourceStateManagementOptions
    {
        UseSession, //defualt
        UseViewstate,
        UseNone
    }
    [Browsable(false)]
    public string SelectedColumnHeaderName
    {
        get
        {
            return ddlFilterExpression.SelectedValue;
        }

    }
    [Browsable(false)]
    public string SearchText
    {
        get
        {
            return txtFilterSearch.Text.Trim();
        }
    }
    [Browsable(false)]
    public DataView DtOriginaldata
    {
        get
        {
            DataView dvOriginal = new DataView();
            if (OriginalData != null)
            {
                dvOriginal = ConvertOriginalDataToDataView(OriginalData);
            }

            return dvOriginal;
        }

    }

    #endregion

    #region Handler Delegates

    public delegate void SearchResetEventHandler();

    #endregion

    #region Control Events

    public event SearchResetEventHandler SearchResetEvent;

    #endregion

    #region Page Events

    protected void Page_Load(object sender, EventArgs e)
    {

        TargetControl.Sorted += new EventHandler(TargetControl_Sorted);
        if (!Page.IsPostBack)
        {
            PopulateConditionsDropdown();
            ddlFilteronditionForNumericType.Visible = false;
            //ddlFilteronditionForNumericType.SelectedIndex = 0;
            PopulateConditionsDropdownForNumericType();
            UniqueKey = Guid.NewGuid().ToString();
            //Session["SearchText"] = null;
            //Session["Field"] = null;
        }
        else
        {
            foreach (ListItem li in ddlFilterExpression.Items)
            {
                if (li != ddlFilterExpression.Items[0])
                {
                    lstcolumnsToSearch.Add(li.Value);
                }
            }
        }


    }

    void TargetControl_Sorted(object sender, EventArgs e)
    {
        UpdateOriginalData();
    }

    private void AttachEventToTargetControl(EventArgs e)
    {
        gvTarget_DataBound(null, e);
    }

    public void RenderControl()
    {
        AttachEventToTargetControl(null);
        //call filter depending on various conditions
        string searchTextSession = SearchText;// (string)Session["SearchText"];
        string SelectedColumnHeaderNameSession = SelectedColumnHeaderName;// (string)Session["Field"];
        //In case of search without any searchtext the search results in reset
        if (searchTextSession != null && searchTextSession.Trim() == "")
        {
            {
                //Reset();

            }
        }
        else if (!string.IsNullOrEmpty(SelectedColumnHeaderNameSession) && !string.IsNullOrEmpty(searchTextSession))
        {
            if (string.IsNullOrEmpty(hiddenValue.Value))
            {
                //Reset(); 
            }
            else
            {
                SetFilterExpression(searchTextSession, SelectedColumnHeaderNameSession);
                Filter();
            }
        }
        else if (string.IsNullOrEmpty(SelectedColumnHeaderNameSession) && !string.IsNullOrEmpty(searchTextSession))
        {
            GetFilterExpressionForFreeTextSearch(searchTextSession, lstcolumnsToSearch);
            Filter();
        }
        //fill search text and dropdownlist as per last performed search
        //if (Session["SearchText"] != null)
        //{
        //    txtFilterSearch.Text = (string)Session["SearchText"];
        //}
        //else
        //{
        //    txtFilterSearch.Text = string.Empty;
        //}
        txtFilterSearch.Text = string.IsNullOrEmpty(SearchText) ? string.Empty : SearchText;

        //if (!string.IsNullOrEmpty(SelectedColumnHeaderName))// if (Session["Field"] != null)
        //{
        //    ListItem liToSelect = ddlFilterExpression.Items.FindByValue(SelectedColumnHeaderName);
        //    if (liToSelect != null)
        //        ddlFilterExpression.SelectedValue = liToSelect.Value.ToString();
        //}

    }
    protected override void OnPreRender(EventArgs e)
    {

        RenderControl();
    }

    protected void gvTarget_DataBound(object sender, EventArgs e)
    {
        string strSelectedValue = ddlFilterExpression.SelectedValue;

        //TODO: remove try catch
        try
        {

            if (TargetControl.DataSource != null)
            {
                if (DtOriginaldata.Table.Rows.Count > 0)
                {
                    searchPanel.Visible = true;
                    GetSearchableColumnHeaderForTargetGrid();
                    if (DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(int)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(Int64)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(long)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(decimal)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(double)))
                    {
                        ddlFilterConditions.Visible = false;
                        ddlFilteronditionForNumericType.Visible = true;
                    }
                    else if (DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(bool)))
                    {
                        ddlFilterConditions.Visible = false;
                        ddlFilteronditionForNumericType.Visible = false;
                    }
                    else
                    {
                        ddlFilterConditions.Visible = true;
                        ddlFilteronditionForNumericType.Visible = false;
                        //ddlFilteronditionForNumericType.SelectedIndex = 0;
                        //ddlFilterConditions.SelectedIndex = 0;
                    }

                }
                else
                {
                    searchPanel.Visible = false;
                }
            }
            //ddlFilterExpression.SelectedValue = string.IsNullOrEmpty(strSelectedValue) ? "Select any expression" : strSelectedValue;

        }
        catch (Exception)
        {
            //todo: handling
        }
    }

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        hiddenValue.Value = txtFilterSearch.Text;
        //Session["SearchText"] = SearchText.Trim().Length > 0 ? SearchText : string.Empty;
        //Session["Field"] = SearchText.Trim().Length > 0 ? SelectedColumnHeaderName : string.Empty;
        RaiseSearchResetEvent();
    }

    protected void btnReset_Click(object sender, EventArgs e)
    {
        RaiseSearchResetEvent();
        Reset();
    }
    private void RaiseSearchResetEvent()
    {
        try
        {
            SearchResetEvent();
        }
        catch (Exception)
        {


        }
    }


    #endregion

    #region Methods
    /// <summary>
    /// Method for retrieving the searchable column header for the target grid
    /// </summary>
    private void GetSearchableColumnHeaderForTargetGrid()
    {
        if (ddlFilterExpression.Items.Count.Equals(0))
        {
            Hashtable columnNames = new Hashtable();
            if (TargetControl.Columns.Count != 0)
            {
                foreach (DataControlField col in TargetControl.Columns)
                {
                    if (col != null)
                        if (!columnNames.Contains(col))
                            if (col.HeaderText != "" || col.AccessibleHeaderText != "")
                            {
                                columnNames.Add(col.HeaderText, col.AccessibleHeaderText);
                            }
                }
                Hashtable requireColumnName = (Hashtable)columnNames.Clone();// new Hashtable();
                if (listExcludedFields != null)
                {
                    foreach (string removedfield in listExcludedFields)
                    {
                        foreach (DictionaryEntry dic in columnNames)
                        {
                            if (dic.Value.ToString().Equals(removedfield))
                            {
                                requireColumnName.Remove(dic.Key);
                            }
                        }
                    }
                    foreach (DictionaryEntry dic in requireColumnName)
                        ddlFilterExpression.Items.Add(new ListItem(dic.Key.ToString(), dic.Value.ToString()));
                    //ddlFilterExpression.Items.Insert(0, new ListItem("Select any expression"));
                }
                else
                {
                    foreach (DictionaryEntry dic in columnNames)
                        ddlFilterExpression.Items.Add(new ListItem(dic.Key.ToString(), dic.Value.ToString()));
                    //ddlFilterExpression.Items.Insert(0, new ListItem("Select any expression"));
                }
            }
            else
            {
                List<string> lstForDdlFilterExp = new List<string>();
                foreach (DataColumn dc in DtOriginaldata.Table.Columns)
                {
                    for (int colCount = 1; colCount < DtOriginaldata.Table.Columns.Count; colCount++)
                    {
                        if (dc != null)
                            if (!lstForDdlFilterExp.Contains(dc.ToString()))
                                lstForDdlFilterExp.Add(dc.ToString());
                    }

                }
                foreach (string strItem in lstForDdlFilterExp)
                    ddlFilterExpression.Items.Add(strItem);
                ddlFilterExpression.Items.Insert(0, new ListItem("Select any expression"));
            }
        }
    }
    /// <summary>
    /// Specific method for requirement in Kohls for narrowing down the search
    /// </summary>
    private void PopulateConditionsDropdown()
    {
        ListItem listItem = new ListItem();
        //ddlFilterConditions.Items.Add("---Select---");
        ddlFilterConditions.Items.Add("Starts with");
        ddlFilterConditions.Items.Add("Has");
        ddlFilterConditions.Items.Add("Ends with");
    }

    private void PopulateConditionsDropdownForNumericType()
    {
        ListItem listItem = new ListItem();
        //ddlFilterConditions.Items.Add("---Select---");
        ddlFilteronditionForNumericType.Items.Add("Greater than");
        ddlFilteronditionForNumericType.Items.Add("Lesser than");
        ddlFilteronditionForNumericType.Items.Add("Greater than equal to");
        ddlFilteronditionForNumericType.Items.Add("Lesser than equal to");
        ddlFilteronditionForNumericType.Items.Add("Equals to");

    }

    /// <summary>
    /// Method for retrieving the filter expression
    /// </summary>
    /// <param name="dc"></param>
    /// <param name="searchText"></param>
    /// <returns>string</returns>
    private string GetFilterExpression(DataColumn dc, string searchText, string strNarrowCondition)
    {
        string filterExpression = "";

        if ((!dc.DataType.Equals(typeof(bool))) && (!dc.DataType.Equals(typeof(DateTime))) && (!dc.DataType.Equals(typeof(int))) && (!dc.DataType.Equals(typeof(Int64))) && (!dc.DataType.Equals(typeof(long))) && (!dc.DataType.Equals(typeof(decimal))) && (!dc.DataType.Equals(typeof(double))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText) && !searchText.Contains("*") && strNarrowCondition == "Has")
                {
                    filterExpression =
                        string.Format("{0} Like '%{1}%'", dc.ColumnName,
                                      searchText.Replace('*', ' ').Replace('%', ' '));
                }
                else if (!string.IsNullOrEmpty(searchText) && strNarrowCondition == "Starts with")
                {
                    searchText = searchText.TrimEnd('*');
                    filterExpression = dc.ColumnName + " " + "Like " + " " + "'" + searchText + "%'";
                }
                else if (!string.IsNullOrEmpty(searchText) && strNarrowCondition == "Ends with")
                {
                    searchText = searchText.TrimStart('*');
                    filterExpression = dc.ColumnName + " " + "Like " + " " + "'%" + searchText + "'";
                }

                else
                {
                    filterExpression = string.Format("{0} Like '%{1}%'", dc.ColumnName, searchText);

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        else if ((dc.DataType.Equals(typeof(DateTime))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                    filterExpression = string.Format("{0} = '{1}'", dc.ColumnName,
                                  searchText.Replace('*', ' ').Replace('%', ' '));
                else
                    filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else if ((dc.DataType.Equals(typeof(int))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                {
                    if (ddlFilteronditionForNumericType.SelectedValue == "Greater than")
                    {
                        filterExpression =
                            string.Format("{0} > {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Greater than equal to")
                    {
                        filterExpression =
                            string.Format("{0} >= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than equal to")
                    {
                        filterExpression =
                            string.Format("{0} <= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than")
                    {
                        filterExpression =
                            string.Format("{0} < {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Equals to")
                    {
                        filterExpression =
                            string.Format("{0} = {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                }
                else
                    filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else if ((dc.DataType.Equals(typeof(Int64))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                    if (ddlFilteronditionForNumericType.SelectedValue == "Greater than")
                    {
                        filterExpression =
                            string.Format("{0} > {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Greater than equal to")
                    {
                        filterExpression =
                            string.Format("{0} >= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than equal to")
                    {
                        filterExpression =
                            string.Format("{0} <= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than")
                    {
                        filterExpression =
                            string.Format("{0} < {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Equals to")
                    {
                        filterExpression =
                            string.Format("{0} = {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else
                        filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else if ((dc.DataType.Equals(typeof(long))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                {
                    if (ddlFilteronditionForNumericType.SelectedValue == "Greater than")
                    {
                        filterExpression =
                            string.Format("{0} > {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Greater than equal to")
                    {
                        filterExpression =
                            string.Format("{0} >= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than equal to")
                    {
                        filterExpression =
                            string.Format("{0} <= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than")
                    {
                        filterExpression =
                            string.Format("{0} < {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Equals to")
                    {
                        filterExpression =
                            string.Format("{0} = {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                }
                else
                    filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else if ((dc.DataType.Equals(typeof(decimal))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                {
                    if (ddlFilteronditionForNumericType.SelectedValue == "Greater than")
                    {
                        filterExpression =
                            string.Format("{0} > {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Greater than equal to")
                    {
                        filterExpression =
                            string.Format("{0} >= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than equal to")
                    {
                        filterExpression =
                            string.Format("{0} <= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than")
                    {
                        filterExpression =
                            string.Format("{0} < {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Equals to")
                    {
                        filterExpression =
                            string.Format("{0} = {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                }
                else
                    filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else if ((dc.DataType.Equals(typeof(double))))
        {
            try
            {
                if (!string.IsNullOrEmpty(searchText))
                {
                    if (ddlFilteronditionForNumericType.SelectedValue == "Greater than")
                    {
                        filterExpression =
                            string.Format("{0} > {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Greater than equal to")
                    {
                        filterExpression =
                            string.Format("{0} >= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than equal to")
                    {
                        filterExpression =
                            string.Format("{0} <= {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Lesser than")
                    {
                        filterExpression =
                            string.Format("{0} < {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                    else if (ddlFilteronditionForNumericType.SelectedValue == "Equals to")
                    {
                        filterExpression =
                            string.Format("{0} = {1}", dc.ColumnName,
                                          searchText.Replace('*', ' ').Replace('%', ' '));
                    }
                }
                else
                    filterExpression = string.Format("{0} = ''", dc.ColumnName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        else
        {
            if (string.IsNullOrEmpty(searchText))
            {
                filterExpression = string.Format("{0} IS NULL", dc.ColumnName);
                return filterExpression; //to see
            }

            else
            {

                filterExpression = string.Format("{0} = {1}", dc.ColumnName,
                                               searchText);

            }
        }

        return filterExpression;
    }
    /// <summary>
    /// Method for setting the filter expression
    /// </summary>
    /// <param name="searchText"></param>
    /// <param name="selectedColumnHeaderName"></param>
    private void SetFilterExpression(string searchText, string selectedColumnHeaderName)
    {
        if (!ddlFilterExpression.Items.Count.Equals(0))
        {
            if (selectedColumnHeaderName != "Select any expression")
            {
                if (DtOriginaldata != null && DtOriginaldata.Table.Rows.Count > 0)
                {

                    filterCriteria = "";
                    try
                    {
                        string strNarrowCondition = ddlFilterConditions.SelectedValue;
                        filterCriteria = GetFilterExpression(DtOriginaldata.Table.Columns[selectedColumnHeaderName],
                                                               searchText, strNarrowCondition);
                    }
                    catch (Exception ex)
                    {
                        ShowErrorMessage();
                    }
                }
            }
            else
            {
                foreach (ListItem colHeaderName in ddlFilterExpression.Items)
                {
                    DataColumn dc = (DtOriginaldata.Table.Columns[colHeaderName.Value]);
                    if (!colHeaderName.Text.Equals(ddlFilterExpression.Items[0].Value))
                    {
                        try
                        {
                            if (dc.DataType == Type.GetType("System.Boolean"))
                                continue;

                            filterCriteria = GetFilterExpressionForFreeTextSearch(searchText, lstcolumnsToSearch);
                        }
                        catch (Exception ex)
                        {
                            ShowErrorMessage();
                        }
                    }
                    else if (colHeaderName.Text.Equals(ddlFilterExpression.Items[0].Value) && DtOriginaldata.Table.Columns.Count == 1)
                    {
                        filterCriteria = GetFilterExpressionForFreeTextSearch(searchText, lstcolumnsToSearch);

                    }
                    else if (colHeaderName.Text.Equals(ddlFilterExpression.Items[0].Value) && DtOriginaldata.Table.Columns.Count > 1)
                    {
                        filterCriteria = GetFilterExpressionForFreeTextSearch(searchText, lstcolumnsToSearch);

                    }
                }
                filterCriteria = filterCriteria.Trim();
                filterCriteria = filterCriteria.TrimEnd(new char[] { 'o', 'r' });
            }
        }

    }
    /// <summary>
    /// Method for generating the filter expression for free text search
    /// </summary>
    /// <param name="searchText"></param>
    /// <returns>string</returns>
    private string GetFilterExpressionForFreeTextSearch(string searchText, List<string> lstcolumnsToSearch)
    {
        string filter = "";
        StringBuilder strFilter = new StringBuilder();
        string strFilterText = "";
        char[] strRemove = {
                               'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
                               's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                               'K', 'L', 'M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

        foreach (DataRow row in DtOriginaldata.Table.Rows)
        {
            int count = row.ItemArray.Count();
            for (int i = 0; i < count; i++)
            {
                if (count == 1)
                {
                    if (row.ItemArray[i].GetType().Equals(typeof(System.Int16)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.Int32)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.Int64)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.UInt16)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.UInt32)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.UInt64)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.Single)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.Decimal)) ||
                        row.ItemArray[i].GetType().Equals(typeof(System.Double)))
                    {
                        filter = "Item =" + searchText;
                    }
                    else if (row.ItemArray[i].GetType().Equals(typeof(System.String)) ||
                             row.ItemArray[i].GetType().Equals(typeof(System.Char)))
                    {
                        filter = "Item Like '%" + searchText + "%'";
                    }
                    else if (row.ItemArray[i].GetType().Equals(typeof(System.DateTime)))
                    {
                        continue;
                    }
                }
                else if (count > 1)
                {
                    foreach (string colName in lstcolumnsToSearch)
                    {
                        DataColumn col = DtOriginaldata.Table.Columns[colName];
                        if (col == null)
                        {
                            continue;
                        }
                        if (col.DataType.Equals(typeof(System.Int16)) || col.DataType.Equals(typeof(System.Int32)) || col.DataType.Equals(typeof(System.Int64)) || col.DataType.Equals(typeof(System.UInt16)) || col.DataType.Equals(typeof(System.UInt32)) || col.DataType.Equals(typeof(System.UInt64)) || col.DataType.Equals(typeof(System.Single)) || col.DataType.Equals(typeof(System.Decimal)))
                        {
                            int charCount = searchText.IndexOfAny(strRemove.ToArray<Char>());
                            if (charCount >= 0)
                                continue;
                            else
                                filter = col + " = " + searchText + " " + "or ";
                        }
                        else if (col.DataType.Equals(typeof(System.String)) ||
                             col.DataType.Equals(typeof(System.Char)))
                        {
                            filter = col + " Like '%" + searchText + "%'" + "" + "or ";
                        }
                        else if (col.DataType.Equals(typeof(System.DateTime)))
                        {
                            continue;
                        }
                        if (!strFilter.ToString().ToLower().Equals(filter))
                        {
                            strFilterText = strFilter.Append(filter).ToString();
                        }
                    }
                    return strFilterText;
                }
            }
        }
        return filter;
    }

    /// <summary>
    /// Method for filtering the grid
    /// </summary>
    private void Filter()
    {
        TargetControl.Visible = true;
        DataView dv = DtOriginaldata;
        if (dv == null || dv.Table == null)
            return;
        //do filter on dv;
        try
        {
            dv.RowFilter = this.filterCriteria;

            if (dv.Count <= 0)
            {
                TargetControl.DataSource = null;
                TargetControl.DataBind();
                ShowErrorMessage();

            }
            else
            {
                lblEmptyMessage.Visible = false;
                TargetControl.DataSource = dv;
                TargetControl.DataBind();
            }

        }
        catch (Exception e)
        {
            if (e.GetBaseException().Message.Equals("Syntax error: Missing operand before 'Or' operator."))
            {
            }
            else
            {
                ShowErrorMessage();
            }
        }


    }
    /// <summary>
    /// method for resetting the search in grid control
    /// </summary>
    public void Reset()
    {
        try
        {
            lblEmptyMessage.Visible = false;
            txtFilterSearch.Text = string.Empty;
            ddlFilterExpression.SelectedIndex = 0;
            ddlFilterConditions.Enabled = true;
            ddlFilterConditions.Visible = true;
            ddlFilteronditionForNumericType.Visible = false;
            ddlFilteronditionForNumericType.SelectedIndex = 0;
            ddlFilterConditions.SelectedIndex = 0;
            TargetControl.Visible = true;
            //Session["SearchText"] = null;
            //Session["Field"] = null;
            //((DataTable)TargetControl.DataSource).DefaultView.Sort = string.Format("{0} {1}", SortExpressionOfTargetControl, SortDirection.Ascending);
            if (OriginalData.GetType().Equals(typeof(DataView)))
            {
                DataView dv = (DataView)OriginalData;
                //remove the filter
                dv.RowFilter = "";
                //apply the sort expression
                if (SortExpressionOfTargetControl != null)
                    dv.Sort = SortExpressionOfTargetControl;
                dv.RowFilter = "";
                TargetControl.DataSource = dv;
            }
            else if (OriginalData.GetType().Equals(typeof(DataTable)))
            {
                DataTable dt = (DataTable)OriginalData;
                //apply the sort expression
                if (SortExpressionOfTargetControl != null)
                    dt.DefaultView.Sort = SortExpressionOfTargetControl;
                dt.DefaultView.RowFilter = "";
                TargetControl.DataSource = dt;
            }
            else
            {
                //just bind the data as it is
                TargetControl.DataSource = OriginalData;
            }
            TargetControl.DataBind();
        }
        catch (Exception ex)
        {

        }

    }
    /// <summary>
    /// Recursive method for finding the child control relative to parent
    /// </summary>
    /// <param name="relativeTo"></param>
    /// <param name="sID"></param>
    /// <returns>Control</returns>
    private Control LocateControl(Control relativeTo, String sID)
    {
        Control _control;
        // look in this control's naming container first
        _control = relativeTo.FindControl(sID);

        // if not found, look in the naming container of the parent ... recursively
        if (_control == null && relativeTo.Parent != null)
            _control = LocateControl(relativeTo.Parent, sID);

        // if still not found then look in the naming container for the Page itself
        if (_control == null && relativeTo.Page != null)
            _control = relativeTo.Page.FindControl(sID);

        // at this point we either found the control or c is null; return it in either case
        return _control;
    }
    /// <summary>
    /// method for showing the error message
    /// </summary>
    private void ShowErrorMessage()
    {
        lblEmptyMessage.Visible = true;
        TargetControl.Visible = false;
    }
    /// <summary>
    /// converts any type of original data from datasource to dataview
    /// </summary>
    /// <param name="originalData"></param>
    /// <returns>DataView</returns>
    private DataView ConvertOriginalDataToDataView(object originalData)
    {
        DataView dvOriginalDataTable;// = (DataTable) originalData;
        if (originalData.GetType().Equals(typeof(DataView)))
        {
            dvOriginalDataTable = (DataView)originalData;
        }
        else if (originalData.GetType().Equals(typeof(DataTable)))
        {
            dvOriginalDataTable = ((DataTable)originalData).DefaultView;
        }
        else //not a dv, not a dt
        {
            //if it's a table, retain the sort
            DataTable dtConverted = ReflectionUtils.ConvertToDataTable(originalData);
            dvOriginalDataTable = new DataView(dtConverted);
        }

        return dvOriginalDataTable;




    }

    /// <summary>
    /// Use this method when the original data of the grid changes
    /// </summary>
    public void UpdateOriginalData()
    {
        RetainedData = TargetControl.DataSource;
        if (RetainedData.GetType().Equals(typeof(DataView)))
        {
            SortExpressionOfTargetControl = ((DataView)RetainedData).Sort;
        }
        else if (RetainedData.GetType().Equals(typeof(DataTable)))
        {
            SortExpressionOfTargetControl = ((DataTable)RetainedData).DefaultView.Sort;
        }
        else
        {
            //no sort property available for datasource other than DataTable/DataView
        }
    }
    ///// <summary>
    ///// Method for finding the sort expression of the target control
    ///// </summary>
    ///// <param name="TargetControl"></param>
    ///// <returns>string</returns>
    //private string GetSortExpression(GridView TargetControl)
    //{
    //    string sortExpression = string.Empty;
    //    for (int i = 0; i < TargetControl.Columns.Count - 1; i++)
    //    {
    //        if (TargetControl.Columns[i].SortExpression != "")
    //        {
    //            sortExpression = TargetControl.Columns[i].SortExpression;
    //        }
    //    }
    //    return sortExpression;
    //}



    #endregion

    protected void ddlFilterExpression_OnSelectedIndexChanged(object sender, EventArgs e)
    {
        if (DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(int)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(Int64)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(long)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(decimal)) || DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(double)))
        {
            ddlFilterConditions.Visible = false;
            ddlFilteronditionForNumericType.Visible = true;
            txtFilterSearch.Text = "";
        }
        else if (DtOriginaldata.Table.Columns[SelectedColumnHeaderName].DataType.Equals(typeof(bool)))
        {
            ddlFilterConditions.Visible = false;
            ddlFilteronditionForNumericType.Visible = false;
            txtFilterSearch.Text = "";
        }
        else
        {
            ddlFilterConditions.Visible = true;
            ddlFilteronditionForNumericType.Visible = false;
            ddlFilteronditionForNumericType.SelectedIndex = 0;
            ddlFilterConditions.SelectedIndex = 0;
            txtFilterSearch.Text = "";
        }
    }
}
